home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 2000 #1 / Amiga Plus CD - 2000 - No. 1.iso / Tools / Dev / Sas-PPC / samplelib2 / libinit.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-12-03  |  11.4 KB  |  397 lines

  1. #define  _USEOLDEXEC_ 1
  2. #include <exec/types.h>
  3. #include <exec/nodes.h>
  4. #include <exec/memory.h>
  5. #include <exec/resident.h>
  6. #include <exec/libraries.h>
  7. #include <exec/execbase.h>
  8. #include <libraries/dos.h>
  9. #include <proto/exec.h>
  10. #include <proto/dos.h>
  11. #include <string.h>
  12. #include <dos/dostags.h>
  13. #include <PowerUP/PPCLib/Interface.h>
  14. #include <PowerUP/PPCLib/tasks.h>
  15. #include <PowerUP/PPCLib/ppc.h>
  16. #include <PowerUP/PPCLib/object.h>
  17. #include <PowerUP/PPCDisslib/PPCDiss.h>
  18. #include <PowerUP/pragmas/ppc_pragmas.h>
  19. #include <PowerUP/clib/ppc_protos.h>
  20. #include <PowerUP/pragmas/ppcdiss_pragmas.h>
  21. #include <PowerUP/clib/ppcdiss_protos.h>
  22.  
  23.  
  24. /* Prototypes */
  25. ULONG __asm _LibExpunge( register __a6 struct MyLibrary *libbase );
  26. ULONG __asm _LibInit   ( register __a0 APTR seglist,
  27.                          register __d0 struct MyLibrary *libbase );
  28.  
  29. int  __saveds __asm __UserLibInit   (register __a6 struct MyLibrary *libbase);
  30. void __saveds __asm __UserLibCleanup(register __a6 struct MyLibrary *libbase);
  31.  
  32. int  __saveds __asm __UserDevInit   (register __d0 long unit,
  33.                                      register __a0 struct IORequest *ior,
  34.                                      register __a6 struct MyLibrary *libbase);
  35. void __saveds __asm __UserDevCleanup(register __a0 struct IORequest *ior,
  36.                                      register __a6 struct MyLibrary *libbase);
  37.  
  38. int  __saveds __asm __libfpinit     (register __a6 struct MyLibrary *libbase);
  39. void __saveds __asm __libfpterm     (register __a6 struct MyLibrary *libbase);
  40. void __saveds __asm Set_ElfEntry    (register __a6 struct MyLibrary *libbase, 
  41.                                      register __d0 long value);
  42.  
  43. struct MyLibrary {
  44.         struct             Library ml_Lib;
  45.         ULONG              ml_SegList;
  46.         ULONG              ml_Flags;
  47.         APTR               ml_ExecBase; /* pointer to exec base  */
  48. #ifndef ONE_GLOBAL_SECTION
  49.         long *             ml_relocs;   /* pointer to relocs.    */
  50.         struct MyLibrary * ml_origbase; /* pointer to original library base  */
  51.         long               ml_numjmps;
  52. #endif
  53.         void *             ml_MyObject; /* pointer to ELF Object */
  54.         long               ml_ElfEntry; /* Entrypoint of Elf stub */
  55.  
  56. };
  57.  
  58. typedef LONG (*myPFL)();   /* pointer to function returning 32-bit int      */
  59.  
  60. /* library initialization table, used for AUTOINIT libraries                */
  61. struct InitTable {
  62.         ULONG        *it_DataSize;       /* library data space size         */
  63.         myPFL        *it_FuncTable;      /* table of entry points           */
  64.         APTR         it_DataInit;        /* table of data initializers      */
  65.         myPFL        it_InitFunc;        /* initialization function to run  */
  66. };
  67.  
  68. #ifndef ONE_GLOBAL_SECTION
  69. long _OSERR;
  70. long __base;
  71. #endif
  72.  
  73. /* symbols generated by blink */
  74. extern char __far _LibID[];             /* ID string                        */
  75. extern char __far _LibName[];           /* Name string                      */
  76. extern char __far RESLEN;               /* size of init data                */
  77. extern long __far NEWDATAL;             /* size of global data              */
  78. extern long __far NUMJMPS;              /* number of jmp vectors to copy    */
  79. extern myPFL _LibFuncTab[];             /* my function table                */
  80. extern long __far _LibVersion;          /* Version of library               */
  81. extern long __far _LibRevision;         /* Revision of library              */
  82.  
  83. long _StackPtr;
  84. long __stack;
  85. long __base;
  86. long _ONEXIT;
  87. struct WBStartup *_WBenchMsg;
  88. struct WBStartup *WBenchMsg;
  89.  
  90.  
  91. #define MYVERSION ((long)&_LibVersion)
  92. #define MYREVISION ((long)&_LibRevision)
  93. #define DATAWORDS ((long)&NEWDATAL)     /* magic to get right tpye of reloc */ 
  94. #define SIZEJMPTAB ((((long)libbase->ml_origbase->ml_numjmps)+3)&~3)
  95.                                         /* size in bytes of jmp table       */
  96.  
  97. /* From libent.o, needed to determine where data is loaded by loadseg       */
  98. extern long far _Libmergeddata; 
  99.  
  100. #define MYLIBRARYSIZE ((sizeof(struct MyLibrary) +3) & ~3)
  101.  
  102.  
  103.  
  104. struct InitTable __far _LibInitTab =  {
  105.         (long *)(&RESLEN+MYLIBRARYSIZE),
  106.         _LibFuncTab,
  107.         NULL,                        /* will initialize my own data */
  108.         _LibInit,
  109. };
  110.  
  111.  
  112. int _chkabort(void)
  113. {
  114.     return 0;
  115. }
  116.  
  117.  
  118.  
  119. __asm ULONG _LibInit( register __a0 APTR seglist,
  120.                       register __d0 struct MyLibrary *libbase )
  121. {
  122. #ifdef ONE_GLOBAL_SECTION
  123.     long *reloc;
  124. #endif
  125.     long *sdata;
  126.     char *ddata;
  127.     long nrelocs;
  128.     struct TagItem MyTags[3];
  129.     extern __far long _ElfObject;
  130.     struct Library *PPCLibBase;
  131.  
  132.     libbase->ml_SegList = (ULONG) seglist;
  133.  
  134.     /* init. library structure (since I don't do automatic data init.) */
  135. #ifdef DEVICE
  136.     libbase->ml_Lib.lib_Node.ln_Type = NT_DEVICE;
  137. #else
  138.     libbase->ml_Lib.lib_Node.ln_Type = NT_LIBRARY;
  139. #endif
  140.     libbase->ml_Lib.lib_Node.ln_Name =  _LibName;
  141.     libbase->ml_Lib.lib_Flags = LIBF_SUMUSED | LIBF_CHANGED;
  142.     libbase->ml_Lib.lib_Version = MYVERSION;
  143.     libbase->ml_Lib.lib_Revision = MYREVISION;
  144.     libbase->ml_Lib.lib_IdString = (APTR) _LibID;
  145. #ifndef ONE_GLOBAL_SECTION
  146.     libbase->ml_relocs = NULL;
  147.     libbase->ml_origbase = libbase;
  148.     sdata = (long *)_LibInitTab.it_FuncTable;
  149.     libbase->ml_numjmps = (long)&NUMJMPS;
  150. #endif
  151.  
  152.     /* load the PPC ELF stub */
  153.     MyTags[0].ti_Tag = PPCELFLOADTAG_ELFADDRESS;
  154.     MyTags[0].ti_Data = (long)&_ElfObject;
  155.     MyTags[1].ti_Tag = PPCELFLOADTAG_ELFNAME;
  156.     MyTags[1].ti_Data = (long)_LibName;
  157.     MyTags[2].ti_Tag = TAG_DONE;
  158.  
  159.  
  160.     if ((PPCLibBase = OpenLibrary("ppc.library",0)) == NULL)
  161.        return NULL;
  162.  
  163.     if (libbase->ml_MyObject=PPCLoadObjectTagList(MyTags))
  164.     {
  165.         struct PPCObjectInfo MyInfo;
  166.  
  167.         MyInfo.Address   =        0;
  168.         MyInfo.Name      =        "__Entry";
  169.         MyTags[0].ti_Tag =        TAG_END;
  170.  
  171.         PPCGetObjectAttrs(libbase->ml_MyObject,
  172.                           &MyInfo,
  173.                           MyTags);
  174.         libbase->ml_ElfEntry = MyInfo.Address;
  175.         Set_ElfEntry(libbase, MyInfo.Address);
  176.         
  177.     }
  178.     else
  179.     {
  180.        CloseLibrary(PPCLibBase);
  181.        return NULL;
  182.     }
  183.     CloseLibrary(PPCLibBase);
  184.  
  185.  
  186.      /* Start of copy of global data after structure */
  187.     ddata = (char *)libbase + MYLIBRARYSIZE; 
  188.  
  189.     sdata = (long *)&_Libmergeddata; /* where loadseg loaded the data */
  190.     memcpy(ddata, (void *)sdata, DATAWORDS*4);
  191.  
  192.     /* perform relocs if we want one global section for all programs */
  193.     /* that have this lib open. If we want a global section for each */
  194.     /* open, copy the relocs, and do them on each open call.         */
  195.     sdata = sdata + DATAWORDS;
  196.     nrelocs = *sdata;
  197. #ifdef ONE_GLOBAL_SECTION
  198.     sdata++;
  199.     while (nrelocs > 0)
  200.     {
  201.        reloc = (long *)((long)ddata + *sdata++);
  202.        *reloc += (long)ddata;
  203.        nrelocs--;
  204.     }
  205.     
  206.     
  207. #ifndef DEVICE
  208.     if (__UserLibInit(libbase) != 0)
  209.        return NULL; /* abort if user init failed */
  210. #endif
  211.  
  212. #else
  213.     if (nrelocs) 
  214.     {
  215.       if ((libbase->ml_relocs = AllocMem((nrelocs * 4) + 4, MEMF_PUBLIC)) == NULL)
  216.         return 0;
  217.       memcpy((void *)libbase->ml_relocs, (void *)sdata, (nrelocs * 4) + 4);
  218.     }
  219. #endif
  220.  
  221.     return ( (ULONG) libbase );
  222. }
  223.  
  224. LONG __asm _LibOpen( 
  225. #ifdef DEVICE
  226.                      register __d0 long unit,
  227.                      register __a1 struct IORequest *ior,
  228. #endif
  229.                      register __a6 struct MyLibrary *libbase )
  230. {
  231. #ifndef ONE_GLOBAL_SECTION
  232.     struct MyLibrary *origbase = libbase;
  233.     struct ExecBase *SysBase = *(struct ExecBase **)4;
  234.     char *newlib;
  235.     long *sdata, *ddata, *reloc;
  236.     long nrelocs;
  237. #endif
  238.  
  239.     /* mark us as having another customer */
  240.     libbase->ml_Lib.lib_OpenCnt++;
  241.  
  242.     /* clear delayed expunges (standard procedure) */
  243.     libbase->ml_Lib.lib_Flags &= ~LIBF_DELEXP;
  244.  
  245. #ifndef ONE_GLOBAL_SECTION
  246.     /* Allocate new lib base */
  247.     newlib = AllocMem((long)(MYLIBRARYSIZE + 
  248.                              ((long)&RESLEN) + SIZEJMPTAB), 
  249.                              MEMF_PUBLIC|MEMF_CLEAR);
  250.  
  251.     if (newlib == NULL) goto error;
  252.         
  253.     /* copy over data */
  254.     memcpy(newlib, (char *)libbase - SIZEJMPTAB, 
  255.            (long)(MYLIBRARYSIZE + DATAWORDS*4 + SIZEJMPTAB));
  256.     
  257.     libbase = (struct MyLibrary *)(newlib+SIZEJMPTAB);
  258.     libbase->ml_relocs = NULL;
  259.     
  260.     /* perform relocs */       
  261.     ddata = (long *)((char *)libbase + MYLIBRARYSIZE); 
  262.     sdata = libbase->ml_origbase->ml_relocs;
  263.     if (sdata)
  264.     {
  265.        nrelocs = *sdata++;
  266.        while (nrelocs > 0)
  267.        {
  268.           reloc = (long *)((long)ddata + *sdata++);
  269.           *reloc += (long)ddata;
  270.           nrelocs--;
  271.        }
  272.     }
  273.  
  274.  
  275.     Set_ElfEntry(libbase, libbase->ml_ElfEntry);
  276.         
  277.  
  278.     /* now we need to flush the cache because we copied the jmp table */
  279.     if (SysBase->LibNode.lib_Version >= 36) 
  280.       CacheClearU();
  281.  
  282. #ifdef DEVICE
  283.     ior->io_Device = (struct Device *)libbase; /* local copy of libary base */
  284. #endif
  285.  
  286.     if (__libfpinit(libbase) || 
  287. #ifdef DEVICE
  288.         __UserDevInit(unit, ior, libbase) != 0
  289. #else
  290.         __UserLibInit(libbase) != 0
  291. #endif
  292.        )
  293.     {
  294.        __libfpterm(libbase);
  295.        FreeMem(newlib, (long)(MYLIBRARYSIZE + 
  296.                        ((long)&RESLEN) + SIZEJMPTAB));
  297. error:
  298.        origbase->ml_origbase->ml_Lib.lib_OpenCnt--;
  299.        return NULL; /* abort if user init failed */
  300.     }
  301.  
  302. #else
  303. #ifdef DEVICE
  304.     if (__UserDevInit(unit, ior, libbase) != 0)
  305.     {
  306.         libbase->ml_Lib.lib_OpenCnt--;
  307.         return NULL;
  308.     }    
  309. #endif
  310. #endif
  311.  
  312.     return ( (LONG) libbase );
  313. }
  314.  
  315. ULONG __asm _LibClose( 
  316. #ifdef DEVICE
  317.                        register __a1 struct IORequest *ior,
  318. #endif                       
  319.                        register __a6 struct MyLibrary *libbase )
  320. {
  321.     ULONG retval = 0;
  322.     
  323. #ifndef ONE_GLOBAL_SECTION
  324.     struct MyLibrary *origbase;
  325.  
  326.     if (libbase != libbase->ml_origbase)
  327.     {
  328. #ifdef DEVICE
  329.        __UserDevCleanup(ior, libbase);
  330. #else
  331.        __UserLibCleanup(libbase);
  332. #endif
  333.        __libfpterm(libbase);
  334.        origbase = libbase->ml_origbase;
  335.        FreeMem((char *)libbase-SIZEJMPTAB, 
  336.                (long)(MYLIBRARYSIZE + ((long)&RESLEN)+SIZEJMPTAB));
  337.        libbase = origbase;
  338.     }
  339. #else
  340. #ifdef DEVICE
  341.     __UserDevCleanup(ior, libbase);
  342. #endif
  343. #endif
  344.  
  345.     if (( --libbase->ml_Lib.lib_OpenCnt == 0 ) &&
  346.                         ( libbase->ml_Lib.lib_Flags & LIBF_DELEXP ))
  347.     {
  348.         /* no more people have me open,
  349.          * and I have a delayed expunge pending
  350.          */
  351.          retval = _LibExpunge( libbase ); /* return segment list        */
  352.     }
  353.  
  354.     return (retval);
  355. }
  356.  
  357. ULONG __asm _LibExpunge( register __a6 struct MyLibrary *libbase )
  358. {
  359.     ULONG seglist = 0;
  360.     LONG  libsize;
  361.     struct Library *PPCLibBase;
  362.  
  363. #ifndef ONE_GLOBAL_SECTION
  364.     libbase = libbase->ml_origbase;
  365. #endif
  366.  
  367.     libbase->ml_Lib.lib_Flags |= LIBF_DELEXP;
  368.     if ( libbase->ml_Lib.lib_OpenCnt == 0 )
  369.     {
  370.         /* really expunge: remove libbase and freemem        */
  371. #ifndef ONE_GLOBAL_SECTION
  372.         if (libbase->ml_relocs)
  373.            FreeMem(libbase->ml_relocs, (*libbase->ml_relocs * 4) + 4);
  374. #else
  375.         __UserLibCleanup(libbase);
  376. #endif
  377.  
  378.         if (PPCLibBase = OpenLibrary("ppc.library",0))
  379.         {
  380.            PPCUnLoadObject(libbase->ml_MyObject);
  381.            CloseLibrary(PPCLibBase);
  382.         }
  383.         
  384.         seglist = libbase->ml_SegList;
  385.  
  386.         Remove( (struct Node *) libbase);
  387.  
  388.         libsize = libbase->ml_Lib.lib_NegSize + libbase->ml_Lib.lib_PosSize;
  389.         FreeMem( (char *) libbase - libbase->ml_Lib.lib_NegSize,(LONG) libsize );
  390.     }
  391.  
  392.     /* return NULL or real seglist                                */
  393.     return ( (ULONG) seglist );
  394. }
  395.  
  396.  
  397.